/*! \file provider.cpp
 *	\brief 
 *
 *	created:	2009/11/20
 *	created:	20:11:2009   18:19
 *	filename: 	o:\main\libs\mem\impl\provider.cpp
 *	file path:	o:\main\libs\mem\impl
 *	file base:	provider
 *	file ext:	cpp
 *	author:		Vitalii Trubchaninov
 *				venngraydog@gmail.com
 */
 
#include "mem/stdafx.h"
#include "mem/impl/provider.h"

#if TT_MEM_ENABLED && TT_MEM_PROFILING

#include <fstream>

#include <time.h>

namespace tt{
namespace mem{
namespace impl{

Provider::Provider()
: m_root("Global")
, m_active_section(NULL)
{
	m_active_section = &m_root;
}

Provider::~Provider()
{

}

BlockInfo* Provider::active_section() const
{
	return m_active_section;
}

BlockInfo* Provider::root_section( const char* section_name )
{
	return m_root.child(section_name);
}

void Provider::section_start(const char* section_name, BlockInfo*& section, BlockInfo*& previous)
{
	previous = m_active_section;
	section = m_active_section = m_active_section->child(section_name);
	section->activate();
}

void Provider::section_start_to_root(const char* section_name, BlockInfo*& section, BlockInfo*& previous)
{
	previous = m_active_section;
	section = m_active_section = m_root.child(section_name);
	section->activate();
}

void Provider::section_end(BlockInfo* section, BlockInfo* previous)
{
	section;
	m_active_section = previous;
}

//////////////////////////////////////////////////////////////////////////
BlockInfo* Provider::register_new( std::size_t size )
{
	*m_active_section += size;
	return m_active_section;
}

BlockInfo* Provider::register_new_array( std::size_t size )
{
	*m_active_section += size;
	return m_active_section;
}

void Provider::register_new(BlockInfo* section, std::size_t size )
{
	*section += size;
}

void Provider::register_new_array( BlockInfo* section, std::size_t size )
{
	*section += size;
}

void Provider::register_delete( BlockInfo* section, std::size_t size )
{
	*section -= size;
}

void Provider::register_delete_array( BlockInfo* section, std::size_t size )
{
	*section -= size;
}

//////////////////////////////////////////////////////////////////////////
#pragma warning(push)
#pragma warning(disable: 4996)

void Provider::serialize( const char* file_name, bool append ) const
{
	unsigned int mode = append ? std::ios_base::out | std::ios_base::app : std::ios_base::out;
	std::ofstream out;
	out.open(file_name, mode);
	{
		time_t t;
		time( &t );
		out << std::endl << std::endl << asctime(localtime(&t)) << std::endl;
		out << "----------------------------------------------------------" << std::endl;
	}
	m_root.serialize(out, 0);
}

#pragma warning(pop)

//////////////////////////////////////////////////////////////////////////
Provider* get_provider()
{
	static Provider s_provider;
	return &s_provider;
}

Provider& g_provider()
{
	static Provider* sp_provider = get_provider();
	return *sp_provider;
}

} //impl
} //mem
} //namespace tt

#endif //TT_MEM_ENABLED && TT_MEM_PROFILING
